package com.weixing.mall.provider.support.excel;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.weixing.mall.base.constant.DatePattern;
import com.weixing.mall.base.exception.BusinessException;
import com.weixing.mall.base.enums.IsEnableEnum;
import com.weixing.mall.core.support.auth.AuthUtil;
import com.weixing.mall.core.support.auth.SysAuth;
import com.weixing.mall.provider.api.model.vo.AgentVo;
import com.weixing.mall.provider.model.domain.Agent;
import com.weixing.mall.provider.model.domain.AgentLog;
import com.weixing.mall.provider.model.domain.AgentRenew;
import com.weixing.mall.provider.model.enums.AgentLogTypeEnum;
import com.weixing.mall.provider.service.IAgentLogService;
import com.weixing.mall.provider.service.IAgentRenewService;
import com.weixing.mall.provider.service.IAgentService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


/**
 * 代理商缴费批量导入
 */
public class AgentRenewImportDataListener extends AnalysisEventListener<AgentRenewExcelData> {
    private static final Logger LOGGER = LoggerFactory.getLogger(AgentRenewImportDataListener.class);
    /**
     * 每隔5条存储数据库，实际使用中可以3000条，然后清理list ，方便内存回收
     */
    private static final int BATCH_COUNT = 5;

    List<AgentRenewExcelData> list = new ArrayList<AgentRenewExcelData>();

    private IAgentService agentService;

    private IAgentRenewService agentRenewService;

    private IAgentLogService agentLogService;

    public AgentRenewImportDataListener(IAgentService agentService, IAgentRenewService agentRenewService, IAgentLogService agentLogService) {
        this.agentService = agentService;
        this.agentRenewService = agentRenewService;
        this.agentLogService = agentLogService;
    }

    @Override
    public void invoke(AgentRenewExcelData data, AnalysisContext analysisContext) {
        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
        list.add(data);
        //这里用不上
        /*if (list.size() >= BATCH_COUNT) {
            saveData();
            list.clear();
        }*/
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();
        LOGGER.info("所有数据解析完成！");
    }

    /**
     * 加上存储数据库
     */
    @Transactional(rollbackFor = Exception.class)
    void saveData() {
        LOGGER.info("{}条数据，开始存储数据库！", list.size());
        if (list.size() == 0) {
            throw new BusinessException("导入数据为空");
        }
        SysAuth auth = AuthUtil.getSysExt();
        //续费数据
        List<AgentRenew> renewList = Lists.newArrayList();
        //代理商更新数据
        List<Agent> agentList = Lists.newArrayList();
        //代理商日志
        List<AgentLog> agentLogList = Lists.newArrayList();
        for (AgentRenewExcelData data : list) {
            AgentVo agentVo = agentService.selectByAgentSn(data.getAgentSn());
            if (ObjectUtil.isEmpty(agentVo)) {
                throw new BusinessException("优惠码：" + data.getAgentSn() + "代理商数据不在");
            }
            AgentRenew agentRenew = new AgentRenew();
            agentRenew.setAgentSn(data.getAgentSn());
            agentRenew.setPayType(data.getPayType());
            agentRenew.setPayChannel(data.getPayChannel());
            agentRenew.setAmount(data.getAmount());
            agentRenew.setEffectStart(DateUtil.parse(data.getEffectStart(), DatePattern.NORM_DATETIME_PATTERN));
            agentRenew.setEffectEnd(DateUtil.parse(data.getEffectEnd(), DatePattern.NORM_DATETIME_PATTERN));
            agentRenew.setRemarks(data.getRemarks());
            agentRenew.setAgentLevel(agentVo.getAgentLevel().getValue());
            agentRenew.setAgentId(agentVo.getId());
            agentRenew.setCreatedBy(auth.getUid());
            agentRenew.setCreator(auth.getRealName());
            agentRenew.setCreatedTime(new Date());
            renewList.add(agentRenew);
            // 更改代理商表到期时间
            Agent agent = new Agent();
            agent.setId(agentVo.getId());
            agent.setLastMaturityTime(agentVo.getMaturityTime());
            agent.setIsEnable(IsEnableEnum.ENABLE.getValue());
            agent.setMaturityTime(DateUtil.parse(data.getEffectEnd(), DatePattern.NORM_DATETIME_PATTERN));
            agentList.add(agent);
            // 记录代理缴费日志
            Agent agentDb = agentService.getById(agent.getId());
            QueryWrapper<AgentRenew> wrapper = new QueryWrapper<AgentRenew>();
            wrapper.eq("agent_id", agent.getId());
            List<AgentRenew> list = agentRenewService.list(wrapper);
            AgentLog agentLog = createLog(auth, agentRenew, agentDb, list);

            agentLogList.add(agentLog);
        }
        if (list.size() != renewList.size()) {
            throw new BusinessException("导入数据数量与数据库匹配数据数量不一致");
        }
        if (renewList.size() > 0) {
            agentRenewService.saveBatch(renewList);
        }
        if (agentList.size() > 0) {
            agentService.updateBatchById(agentList);
        }

        if (CollUtil.isNotEmpty(agentLogList)){
            agentLogService.saveBatch(agentLogList);
        }
        LOGGER.info("存储数据库成功！");
    }


    /**
     * 记录代理缴费日志
     *
     * @param auth             当前登录用户
     * @param agentRenew       缴费记录
     * @param agent            代理商
     * @param list             历史缴费记录
     * @return 缴费日志
     */
    private AgentLog createLog(SysAuth auth, AgentRenew agentRenew, Agent agent, List<AgentRenew> list) {
        AgentLog log = new AgentLog();
        log.setAgentId(agent.getId());
        log.setAgentSn(agent.getAgentSn());
        log.setAgentName(agent.getAgentName());
        log.setAgentLevel(agent.getAgentLevel());
        log.setMobile(agent.getMobile());
        log.setWechatNum(agent.getWechatNum());
        log.setOperatorId(auth.getUid());
        log.setOperatorName(auth.getRealName());
        log.setAmount(agentRenew.getAmount());
        if (CollUtil.isEmpty(list)) {
            log.setLogType(AgentLogTypeEnum.ZHSK.getValue());
        } else {
            log.setLogType(AgentLogTypeEnum.ZSXF.getValue());
        }
        log.setCustomerId(auth.getUid());
        log.setCustomerName(auth.getRealName());
        return log;
    }
}
